<?php

/**
 * Webman gRPC客户端示例
 * 
 * 本示例展示了如何使用优化后的gRPC客户端，包括：
 * 1. 基本的gRPC客户端调用
 * 2. 连接池使用
 * 3. 流式调用
 * 4. 性能监控
 * 5. 错误处理和重试
 */

require_once __DIR__ . '/vendor/autoload.php';

use WebmanGrpc\Client\GrpcClient;

// 示例1: 基本客户端调用
echo "=== 示例1: 基本客户端调用 ===\n";

try {
    // 创建客户端
    $client = new GrpcClient('127.0.0.1:50051', [
        'timeout' => 10,
        'credentials' => \Grpc\ChannelCredentials::createInsecure(),
        'retry' => 3,
        'connection_pool' => [
            'max_connections' => 5,
            'max_lifetime' => 300,
        ],
    ]);
    
    echo "gRPC客户端创建成功\n";
    
    // 注意：这里使用一个假设的请求类，实际使用时需要替换为您的Protobuf生成的类
    // $request = new Helloworld\HelloRequest();
    // $request->setName('World');
    
    // 由于没有实际的gRPC服务，这里只是演示代码结构
    echo "准备发送请求...\n";
    
    // $response = $client->call('SayHello', $request);
    // echo "响应: " . $response->getMessage() . "\n";
    
    // 关闭客户端
    $client->close();
    echo "客户端已关闭\n";
    
} catch (\Exception $e) {
    echo "错误: " . $e->getMessage() . "\n";
}

// 示例2: 连接池统计
echo "\n=== 示例2: 连接池统计 ===\n";

$poolStats = GrpcClient::getConnectionPoolStats();
echo "连接池统计: " . json_encode($poolStats, JSON_PRETTY_PRINT) . "\n";

// 示例3: 序列化统计
echo "\n=== 示例3: 序列化统计 ===\n";

$serializationStats = GrpcClient::getSerializationStats();
echo "序列化统计: " . json_encode($serializationStats, JSON_PRETTY_PRINT) . "\n";

// 示例4: 性能监控
echo "\n=== 示例4: 性能监控 ===\n";

// 启用性能监控
GrpcClient::enablePerformanceMonitoring();

// 模拟一些请求
for ($i = 0; $i < 3; $i++) {
    try {
        $client = new GrpcClient('127.0.0.1:50051', [
            'timeout' => 5,
            'credentials' => \Grpc\ChannelCredentials::createInsecure(),
        ]);
        
        // 这里只是模拟请求，实际使用时需要替换为真实的请求
        echo "模拟请求 $i\n";
        
        // 关闭客户端
        $client->close();
    } catch (\Exception $e) {
        echo "请求 $i 失败: " . $e->getMessage() . "\n";
    }
}

// 获取性能数据
$performanceData = GrpcClient::getPerformanceData();
echo "性能数据: " . json_encode($performanceData, JSON_PRETTY_PRINT) . "\n";

// 获取请求历史
$requestHistory = GrpcClient::getRequestHistory();
echo "请求历史: " . json_encode($requestHistory, JSON_PRETTY_PRINT) . "\n";

// 生成性能报告
$report = GrpcClient::generatePerformanceReport();
echo "\n性能报告:\n";
echo $report . "\n";

// 示例5: 流式调用
echo "\n=== 示例5: 流式调用 ===\n";

try {
    $client = new GrpcClient('127.0.0.1:50051', [
        'timeout' => 10,
        'credentials' => \Grpc\ChannelCredentials::createInsecure(),
        'stream_processor' => [
            'max_memory_usage' => 50 * 1024 * 1024, // 50MB
            'batch_size' => 100,
            'memory_monitoring_enabled' => true,
        ],
    ]);
    
    echo "准备进行流式调用...\n";
    
    // 注意：这里使用假设的请求类，实际使用时需要替换为您的Protobuf生成的类
    // $request = new Helloworld\StreamRequest();
    // $request->setCount(10);
    
    // 服务端流
    // $stream = $client->stream('ServerStream', $request);
    // foreach ($stream->responses() as $response) {
    //     echo "流式响应: " . $response->getMessage() . "\n";
    // }
    
    // 双向流
    // $bidirectionalStream = $client->bidirectionalStream('BidirectionalStream');
    // for ($i = 0; $i < 5; $i++) {
    //     $request = new Helloworld\StreamRequest();
    //     $request->setMessage("Message $i");
    //     $bidirectionalStream->write($request);
    // }
    // 
    // $bidirectionalStream->writesDone();
    // 
    // while ($response = $bidirectionalStream->read()) {
    //     echo "双向流响应: " . $response->getMessage() . "\n";
    // }
    // 
    // $bidirectionalStream->close();
    
    echo "流式调用准备完成（实际调用需要gRPC服务）\n";
    
    // 关闭客户端
    $client->close();
    
} catch (\Exception $e) {
    echo "流式调用错误: " . $e->getMessage() . "\n";
}

// 示例6: 错误处理和重试
echo "\n=== 示例6: 错误处理和重试 ===\n";

try {
    $client = new GrpcClient('127.0.0.1:50053', // 使用一个不存在的端口
        [
            'timeout' => 5,
            'credentials' => \Grpc\ChannelCredentials::createInsecure(),
            'retry' => 2,
            'backoff' => [
                'initial' => 100, // 初始延迟，毫秒
                'max' => 1000,    // 最大延迟，毫秒
                'multiplier' => 2, // 延迟倍数
            ],
        ]
    );
    
    echo "尝试连接到不存在的服务...\n";
    
    // 这个请求会失败，但会自动重试
    // $request = new Helloworld\HelloRequest();
    // $request->setName('World');
    // 
    // $response = $client->call('SayHello', $request);
    
    // 关闭客户端
    $client->close();
    
} catch (\Exception $e) {
    echo "预期的错误: " . $e->getMessage() . "\n";
}

echo "\n客户端示例执行完毕\n";